package com.sxj.PDMS.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sxj.PDMS.common.ErrorCode;
import com.sxj.PDMS.exception.BusinessException;
import com.sxj.PDMS.mapper.ActivistApplicationInformationListMapper;
import com.sxj.PDMS.mapper.StudentMapper;
import com.sxj.PDMS.model.vo.DevelopTheObjectApplicationInformationListVO;
import com.sxj.PDMS.model.vo.ListOfProbationaryPartyApplicationInformationVO;
import com.sxj.PDMS.model.vo.PagingQueryResponse;
import com.sxj.PDMS.model.entity.ActivistApplicationInformationList;
import com.sxj.PDMS.model.entity.DevelopTheObjectApplicationInformationList;
import com.sxj.PDMS.model.entity.Student;
import com.sxj.PDMS.service.DevelopTheObjectApplicationInformationListService;
import com.sxj.PDMS.mapper.DevelopTheObjectApplicationInformationListMapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.text.ParseException;
import java.util.Date;
import java.util.List;

import static com.sxj.PDMS.utils.VerifyUtil.changeDate;

/**
* @author 503c'j
* @description 针对表【develop_the_object_application_information_list(发展对象申请信息列表)】的数据库操作Service实现
* @createDate 2024-06-13 14:52:17
*/
@Service
@Slf4j
public class DevelopTheObjectApplicationInformationListServiceImpl extends ServiceImpl<DevelopTheObjectApplicationInformationListMapper, DevelopTheObjectApplicationInformationList>
    implements DevelopTheObjectApplicationInformationListService{
    @Autowired
    private StudentMapper studentMapper;
    @Autowired
    private DevelopTheObjectApplicationInformationListMapper developTheObjectApplicationInformationListMapper;

    @Autowired
    private ActivistApplicationInformationListMapper activistApplicationInformationListMapper;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void registerDevelopTheObjectApplicationBatch(List<DevelopTheObjectApplicationInformationList> list) {
            log.info("批量注册发展对象");
            list.forEach(developTheObjectApplicationInformationList -> {
                // 1. 校验
                if (StringUtils.isAnyBlank(developTheObjectApplicationInformationList.getStudentNumber())
                        && developTheObjectApplicationInformationList.getTimeOfApplication() == null &&
                        developTheObjectApplicationInformationList.getBranchTime() == null &&
                        developTheObjectApplicationInformationList.getDetermineActivistTime()==null&&
                        developTheObjectApplicationInformationList.getDateOfApplicationForPartyMembership()==null
                ) {
                    throw new BusinessException(ErrorCode.PARAMS_ERROR, "参数为空");
                }
                if (developTheObjectApplicationInformationList.getStudentNumber().length() != 10) {
                    throw new BusinessException(ErrorCode.PARAMS_ERROR, developTheObjectApplicationInformationList.getStudentNumber() + "的学号有误");
                }
                synchronized (developTheObjectApplicationInformationList.getStudentNumber().intern()) {

                    //在学生表里查看状态，看能否插
                    QueryWrapper<Student> queryWrapper = new QueryWrapper<>();
                    queryWrapper.eq("student_number", developTheObjectApplicationInformationList.getStudentNumber());
                    //todo:待优化
                    Integer statue = studentMapper.selectOne(queryWrapper).getStatue();
                    if(statue<3){
                        throw new BusinessException(ErrorCode.PARAMS_ERROR, developTheObjectApplicationInformationList.getStudentNumber() + "不能越级");
                    }
                    if(statue>3){
                        throw new BusinessException(ErrorCode.PARAMS_ERROR, developTheObjectApplicationInformationList.getStudentNumber() + "不能倒退");
                    }

                    //在积极分子表里存在
                    QueryWrapper<ActivistApplicationInformationList> queryWrapperActivist = new QueryWrapper<>();
                    queryWrapperActivist.eq("student_number", developTheObjectApplicationInformationList.getStudentNumber());
                    long activistCount = activistApplicationInformationListMapper.selectCount(queryWrapperActivist);
                    if (activistCount <= 0) {
                        throw new BusinessException(ErrorCode.PARAMS_ERROR, developTheObjectApplicationInformationList.getStudentNumber() + "的账号不存在");
                    }
                    //确定积极分子时间一致
                    Date date = activistApplicationInformationListMapper.selectOne(queryWrapperActivist).getBranchTime();
                    java.sql.Date determineActivistTime = null;
                    try {
                        determineActivistTime = changeDate(date);
                    } catch (ParseException e) {
                        throw new RuntimeException(e);
                    }


                    if(!determineActivistTime.equals(developTheObjectApplicationInformationList.getDetermineActivistTime())){
                        throw new BusinessException(ErrorCode.PARAMS_ERROR, developTheObjectApplicationInformationList.getStudentNumber() + "的确定积极分子时间不一样");
                    }
                    //入党申请时间一致
                    Date date1 = activistApplicationInformationListMapper.selectOne(queryWrapperActivist).getDateOfApplicationForPartyMembership();
                    java.sql.Date dateOfApplication = null;
                    try {
                        dateOfApplication = changeDate(date1);
                    } catch (ParseException e) {
                        throw new RuntimeException(e);
                    }

                    if(!dateOfApplication.equals(developTheObjectApplicationInformationList.getDateOfApplicationForPartyMembership())){
                        throw new BusinessException(ErrorCode.PARAMS_ERROR, developTheObjectApplicationInformationList.getStudentNumber() + "的入党申请日期不一样");
                    }

                    // 在发展对象表里账户不能重复
                    QueryWrapper<DevelopTheObjectApplicationInformationList> queryWrapper1 = new QueryWrapper<>();
                    queryWrapper1.eq("student_number", developTheObjectApplicationInformationList.getStudentNumber());

                    long developTheObjectApplicationCount = developTheObjectApplicationInformationListMapper.selectCount(queryWrapper1);

                    if (developTheObjectApplicationCount > 0) {
                        throw new BusinessException(ErrorCode.PARAMS_ERROR, developTheObjectApplicationInformationList.getStudentNumber() + "的账号已存在");
                    }

                    // 2. 插入数据
                    int inserted = developTheObjectApplicationInformationListMapper.insert(developTheObjectApplicationInformationList);
                    if (inserted < 0) {
                        throw new BusinessException(ErrorCode.SYSTEM_ERROR, "注册失败，数据库错误");
                    }

                    // 3.更新积极分子表
                    activistApplicationInformationListMapper.delete(queryWrapperActivist);
                    //4.更新学生表
                    Student student = new Student();
                    student.setStudentNumber(developTheObjectApplicationInformationList.getStudentNumber());
                    // todo 用常量代替
                    student.setStatue(4);
                    studentMapper.updateById(student);
                }
            });
        }
    @Override
    public PagingQueryResponse<DevelopTheObjectApplicationInformationListVO> selectAll(Integer page, Integer pageSize) {
        Integer start = (page - 1) * pageSize;
        List<DevelopTheObjectApplicationInformationListVO> developTheObjectApplicationInformationLists = developTheObjectApplicationInformationListMapper.selectAll(start, pageSize);
        Long total = developTheObjectApplicationInformationListMapper.selectTotal();
        PagingQueryResponse<DevelopTheObjectApplicationInformationListVO> pagingQueryResponse = new PagingQueryResponse<>();

        pagingQueryResponse.setRows(developTheObjectApplicationInformationLists);

        pagingQueryResponse.setTotal(total);

        return pagingQueryResponse;
    }

    @Override
    public PagingQueryResponse<DevelopTheObjectApplicationInformationListVO> developTheObjectApplicationInformationList(Integer page, Integer pageSize, String studentNumber, String name) {
        Integer start = (page - 1) * pageSize;

        List<DevelopTheObjectApplicationInformationListVO> developTheObjectApplicationInformationLists = developTheObjectApplicationInformationListMapper.selectByNumberOrName(start, pageSize,studentNumber,name);
        Long total = developTheObjectApplicationInformationListMapper.selectTotalByNumberOrName(studentNumber,name);

        PagingQueryResponse<DevelopTheObjectApplicationInformationListVO> pagingQueryResponse = new PagingQueryResponse<>();
        pagingQueryResponse.setRows(developTheObjectApplicationInformationLists);
        pagingQueryResponse.setTotal(total);

        return pagingQueryResponse;

    }

    @Override
    public void selectAllStudentAndDownload(String studentNumber, String name, HttpServletResponse response) {
        List<DevelopTheObjectApplicationInformationListVO> developTheObjectApplicationInformationListVOList = developTheObjectApplicationInformationListMapper.selectAllStudentAndDownload(studentNumber,name);
        if (developTheObjectApplicationInformationListVOList == null || developTheObjectApplicationInformationListVOList.isEmpty()) {
            throw new BusinessException(ErrorCode.NOT_FOUND_ERROR, "没有符合条件的学生");
        }
        // 2.通过POI将数据写入template/发展对象基本信息表.xlsx文件
        InputStream stream = this.getClass().getClassLoader().getResourceAsStream("template/发展对象基本信息表.xlsx");
        try {
            XSSFWorkbook excel = new XSSFWorkbook(stream);

            // 填充数据
            for (int i = 0; i < developTheObjectApplicationInformationListVOList.size(); i++) {
                XSSFSheet sheet = excel.getSheetAt(0);
                // 获取第i+1行
                XSSFRow row = sheet.createRow(i + 2);
                DevelopTheObjectApplicationInformationListVO developTheObjectApplicationInformationListVO = developTheObjectApplicationInformationListVOList.get(i);
                row.createCell(0).setCellValue(developTheObjectApplicationInformationListVO.getSerialNumber());
                row.createCell(1).setCellValue(developTheObjectApplicationInformationListVO.getStudentNumber());
                row.createCell(2).setCellValue(developTheObjectApplicationInformationListVO.getGrade());
                row.createCell(3).setCellValue(developTheObjectApplicationInformationListVO.getName());
                row.createCell(4).setCellValue(developTheObjectApplicationInformationListVO.getDateOfApplicationForPartyMembership());
                row.createCell(5).setCellValue(developTheObjectApplicationInformationListVO.getDetermineActivistTime());
                row.createCell(6).setCellValue(developTheObjectApplicationInformationListVO.getTimeOfApplication());
                row.createCell(7).setCellValue(developTheObjectApplicationInformationListVO.getBranchTime());
            }

            XSSFSheet sheet = excel.getSheetAt(0);
            XSSFRow row = sheet.createRow(developTheObjectApplicationInformationListVOList.size() + 2);
            row.createCell(0).setCellValue("下载时间:" + new Date().toString());


            // 3.通过输出流将文件下载到浏览器
            ServletOutputStream outputStream = response.getOutputStream();

            excel.write(outputStream);

            // 4.关闭资源
            excel.close();
            outputStream.close();

            log.info("发展对象基本信息表.xlsx下载成功");

        } catch (IOException e) {
            throw new BusinessException(ErrorCode.SYSTEM_ERROR, "文件下载失败");
        }
    }
}




